#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
格式化工具模块
提供SQL和数据格式化相关的辅助函数
"""

import logging
import sqlparse
from typing import Dict, List, Any, Optional, Union
import re


# 初始化日志记录器
logger = logging.getLogger("format_utils")


def format_sql(sql: str) -> str:
    """格式化SQL语句
    
    Args:
        sql: 原始SQL语句
        
    Returns:
        格式化后的SQL语句
    """
    try:
        # 使用sqlparse格式化SQL
        formatted = sqlparse.format(
            sql,
            keyword_case='upper',
            identifier_case='lower',
            reindent=True,
            indent_width=4,
            strip_comments=False,
            wrap_after=80
        )
        return formatted
    except Exception as e:
        logger.error(f"SQL格式化失败: {str(e)}")
        return sql


def format_file_size(size_bytes: int) -> str:
    """格式化文件大小
    
    Args:
        size_bytes: 文件字节大小
        
    Returns:
        格式化后的文件大小字符串
    """
    if size_bytes < 0:
        return "0 B"
    
    size_names = ("B", "KB", "MB", "GB", "TB", "PB")
    i = 0
    while size_bytes >= 1024 and i < len(size_names) - 1:
        size_bytes /= 1024
        i += 1
        
    return f"{size_bytes:.2f} {size_names[i]}"


def format_data_preview(data, max_rows: int = 5) -> str:
    """格式化数据预览
    
    Args:
        data: 数据对象
        max_rows: 最大显示行数
        
    Returns:
        格式化后的预览字符串
    """
    # 检查数据类型
    if hasattr(data, 'columns') and hasattr(data, 'fetchall'):
        # DuckDB 结果集
        columns = data.columns
        rows = data.fetchall(max_rows)
    elif isinstance(data, dict) and 'columns' in data and 'data' in data:
        # 字典格式的数据
        columns = data['columns']
        rows = data['data'][:max_rows]
    else:
        return "无法预览数据"
    
    # 计算每列的最大宽度
    col_widths = [len(str(col)) for col in columns]
    for row in rows:
        for i, cell in enumerate(row):
            if i < len(col_widths):
                col_widths[i] = max(col_widths[i], len(str(cell)))
    
    # 格式化输出
    header = " | ".join(str(col).ljust(width) for col, width in zip(columns, col_widths))
    separator = "-+-".join("-" * width for width in col_widths)
    
    result = [header, separator]
    
    for row in rows:
        formatted_row = " | ".join(str(cell).ljust(width) if cell is not None else "NULL".ljust(width) 
                                 for cell, width in zip(row, col_widths))
        result.append(formatted_row)
    
    return "\n".join(result)


def format_duration(seconds: Union[int, float]) -> str:
    """格式化时间间隔
    
    Args:
        seconds: 秒数
        
    Returns:
        格式化后的时间字符串
    """
    if seconds < 0.001:  # 小于1毫秒
        return f"{seconds * 1000000:.2f} 微秒"
    elif seconds < 1:    # 小于1秒
        return f"{seconds * 1000:.2f} 毫秒"
    elif seconds < 60:   # 小于1秒
        return f"{seconds:.2f} 秒"
    else:
        minutes = seconds // 60
        secs = seconds % 60
        return f"{int(minutes)} 分 {secs:.2f} 秒"


def sanitize_table_name(name: str) -> str:
    """清理表名，替换不合法字符
    
    Args:
        name: 原始表名
        
    Returns:
        清理后的表名
    """
    # 替换非字母数字字符为下划线
    sanitized = re.sub(r'[^\w]', '_', name)
    
    # 确保以字母开头
    if sanitized and not sanitized[0].isalpha():
        sanitized = 'tbl_' + sanitized
        
    # 如果为空，返回默认名称
    if not sanitized:
        sanitized = 'table'
        
    return sanitized


def format_error_message(message: str, max_length: int = 200) -> str:
    """格式化错误消息
    
    Args:
        message: 原始错误消息
        max_length: 最大长度
        
    Returns:
        格式化后的错误消息
    """
    if not message:
        return "未知错误"
        
    # 移除多余的空白字符
    cleaned = re.sub(r'\s+', ' ', message).strip()
    
    # 限制长度
    if len(cleaned) > max_length:
        return cleaned[:max_length] + "..."
        
    return cleaned


def value_to_str(value: Any) -> str:
    """将任意值转换为字符串表示
    
    Args:
        value: 任意值
        
    Returns:
        字符串表示
    """
    if value is None:
        return "NULL"
    elif isinstance(value, (list, tuple, set)):
        items = [value_to_str(item) for item in value]
        return f"[{', '.join(items)}]"
    elif isinstance(value, dict):
        items = [f"{k}: {value_to_str(v)}" for k, v in value.items()]
        return f"{{{', '.join(items)}}}"
    elif isinstance(value, (int, float, bool)):
        return str(value)
    else:
        return f"'{str(value)}'"
